package com.xci.platform.helper;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;

/**
 * Token操作类
 */
public class TokenHelper {

    /**
     * 签名秘钥
     */
    private static final String SECRET = "spring.xci96716.com";

    /**
     * 生成token
     * @param id 一般传入userName
     */
    public static String createJwtToken(String id){
        String iss = "www.xci96716.com";
        String sub = "winform.app";
        // iss: jwt签发者
        // sub: jwt所面向的用户
        // aud: 接收jwt的一方
        // exp: jwt的过期时间，这个过期时间必须要大于签发时间
        // nbf: 定义在什么时间之前，该jwt都是不可用的
        // iat: jwt的签发时间
        // jti: jwt的唯一身份标识，主要用来作为一次性token,从而回避重放攻击

        return createJwtToken(id, iss, sub, DateUtil.date().offset(DateField.MINUTE,120));
    }

    /**
     * 生成Token
     * @param id 编号
     * @param issuer 该JWT的签发者，是否使用是可选的
     * @param subject 该JWT所面向的用户，是否使用是可选的；
     * @param expDate 过期
     * @return token String
     */
    public static String createJwtToken(String id, String issuer, String subject, Date expDate) {

        // 签名算法 ，将对token进行签名
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        // 生成签发时间
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        // 通过秘钥签名JWT
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(SECRET);
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());


        JwtBuilder builder = Jwts.builder()
                .setId(id)
                .setIssuedAt(now)
                .setSubject(subject)
                .setIssuer(issuer)
                .signWith(signatureAlgorithm, signingKey);

        if (expDate!=null) {
            builder.setExpiration(expDate);
        }

        // Builds the JWT and serializes it to a compact, URL-safe string
        return builder.compact();
    }

    // Sample method to validate and read the JWT
    public static Claims parseJWT(String jwt) {
        // This line will throw an exception if it is not a signed JWS (as expected)
        Claims claims = Jwts.parser()
                .setSigningKey(DatatypeConverter.parseBase64Binary(SECRET))
                .parseClaimsJws(jwt).getBody();

        return claims;
    }

    // public static void main(String[] args) {
    //     //System.out.println(createJwtToken("admin"));
    //     Date exp = parseJWT("eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJhZG1pbiIsImlhdCI6MTUzMTczMjUyOSwic3ViIjoibHVvbW91cmVuQHh4eC5jb20iLCJpc3MiOiJ3d3cuZ3Vhbmd5dWFuYmouY29tIiwiZXhwIjoxNTMxNzMyNTg5fQ.7XIyjkeuEqa7UqMDf_GbCID992wqTyG3PyE-54vcbb8").getExpiration();
    //     DateTime dateTime = new DateTime(exp);
    //     System.out.println(dateTime.toString());
    // }
}
